package com.example.java_gobang.game;
import com.example.java_gobang.JavaGobangApplication;
import com.example.java_gobang.dao.UserMapper;
import com.example.java_gobang.model.User;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.UUID;

@Data
public class Room {
    private final int MAX_ROW = 15;
    private final int MAX_COL = 15;
    private  String roomId;
    private  User user1;
    private  User user2;
    private  Integer whiteUserId;
    private int[][] board = new int[MAX_ROW][MAX_COL];


    //@Autowired
    ObjectMapper objectMapper;
    //@Autowired
    OnlineUserManager onlineUserManager;

    RoomManager roomManager;
    UserMapper userMapper;
    public Room(){
        roomId = UUID.randomUUID().toString();
        objectMapper = JavaGobangApplication.context.getBean(ObjectMapper.class);
        onlineUserManager = JavaGobangApplication.context.getBean(OnlineUserManager.class);
        roomManager = JavaGobangApplication.context.getBean(RoomManager.class);
        userMapper = JavaGobangApplication.context.getBean(UserMapper.class);
    }

    public void putChess(String payload) throws IOException {
        GameRequest request = objectMapper.readValue(payload, GameRequest.class);
        GameResponse response = new GameResponse();
        //1落子
        int chess = request.getUserId() == user1.getUserId() ? 1 : 2;
        int row = request.getRow();
        int col = request.getCol();
        if(board[row][col] != 0){
            System.out.println("落子位置有误 " + request);
            return;
        }
        board[row][col] = chess;
        printBoard(board);
        //2检查游戏是否结束
        int winner = checkWinner(chess, row, col);
        //3发送响应给玩家
        response.setMessage("putChess");
        response.setUserId(request.getUserId());
        response.setRow(row);
        response.setCol(col);
        response.setWinner(winner);

        WebSocketSession session1 = onlineUserManager.getSessionByRoom(user1.getUserId());
        WebSocketSession session2 = onlineUserManager.getSessionByRoom(user2.getUserId());
        if(session1 == null){
            System.out.println("玩家1掉线");
            response.setWinner(user2.getUserId());
        }

        if(session2 == null){
            System.out.println("玩家2掉线");
            response.setWinner(user1.getUserId());
        }

        if(session1 != null){
            session1.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }

        if(session2 != null){
            session2.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }

        //胜负已分
        if(response.getWinner() != 0){
            int loseUserId = response.getWinner() == user1.getUserId() ? user2.getUserId() : user1.getUserId();
            userMapper.updateWin(response.getWinner());
            userMapper.updateLose(loseUserId);
            roomManager.removeRoom(roomId, user1.getUserId(), user2.getUserId());
        }


    }

    private void printBoard(int[][] board) {
        System.out.println("[打印棋盘信息]");
        System.out.println("=====================================");
        for (int r = 0; r < MAX_ROW; r++) {
            for (int c = 0; c < MAX_COL; c++) {
                System.out.print(board[r][c] + " ");
            }
            System.out.println();
        }
        System.out.println("=====================================");
    }

    private int checkWinner(int chess, int row, int col) {
        //验证所有行
        for (int c = col - 4; c <= col; c++) {
            try {
                if(board[row][c] == chess
                        && board[row][c + 1] == chess
                        && board[row][c + 2] == chess
                        && board[row][c + 3] == chess
                        && board[row][c + 4] == chess){
                    return chess == 1 ? user1.getUserId() : user2.getUserId();
                }
            }catch (ArrayIndexOutOfBoundsException e){
                continue;
            }
        }

        //验证所有列
        for (int r = row - 4; r <= row; r++) {
            try{
                if(board[r][col] == chess
                        && board[r + 1][col] == chess
                        && board[r + 2][col] == chess
                        && board[r + 3][col] == chess
                        && board[r + 4][col] == chess){
                    return chess == 1 ? user1.getUserId() : user2.getUserId();
                }
            }catch (ArrayIndexOutOfBoundsException e){
                continue;
            }
        }

        //验证对角线
        for (int r = row - 4, c = col - 4; r <= row && c <= col; r++, c++) {
            try{
                if(board[r][c] == chess
                        && board[r + 1][c + 1] == chess
                        && board[r + 2][c + 2] == chess
                        && board[r + 3][c + 3] == chess
                        && board[r + 4][c + 4] == chess){
                    return chess == 1 ? user1.getUserId() : user2.getUserId();
                }
            }catch (ArrayIndexOutOfBoundsException e){
                continue;
            }
        }

        for (int r = row - 4, c = col + 4; r <= row && c >= col; r++, c--) {
            try{
                if(board[r][c] == chess
                        && board[r + 1][c - 1] == chess
                        && board[r + 2][c - 2] == chess
                        && board[r + 3][c - 3] == chess
                        && board[r + 4][c - 4] == chess){
                    return chess == 1 ? user1.getUserId() : user2.getUserId();
                }
            }catch (ArrayIndexOutOfBoundsException e){
                continue;
            }
        }
        return 0;
    }
}
